package tree

import "fmt"

type Node struct {
	Value       int
	Left, Right *Node
}

// 如何创建一个struct
func CreateStruct() {
	// 1. 创建对象，go语言没有构造方法，提供了默认的构造方法
	var root Node
	root = Node{Value: 3}
	root.Left = &Node{}
	root.Right = &Node{5, nil, nil}
	// 成员一律采用点进行访问
	root.Right.Left = new(Node)
	// 如果想要自定义构造怎么办？那就使用工厂函数指定创建对象
	root.Left.Right = CreateNode(2)

	// 当然，还可以建立struct的数组
	nodes := []Node{
		{Value: 3},
		{},
		{6, nil, nil},
	}
	fmt.Println(nodes)

	// 调用方法设置值，调用打印方法
	root.Right.Left.SetValue(4)
	fmt.Println("root.Right.Left")
	root.Right.Left.Print()
	root.Print()
	root.SetValue(100)

	// 设置值
	pRoot := &root
	pRoot.Print()
	pRoot.SetValue(200)
	pRoot.Print()
	root.Print()

	// nil调用方法
	var yRoot *Node
	yRoot.SetValue(1)
	yRoot = &root
	yRoot.SetValue(300)
	yRoot.Print()

	// 遍历
	fmt.Println("Traverse")
	root.Traverse()
}

// CreateNode 工厂函数指定创建对象
func CreateNode(value int) *Node {
	return &Node{Value: value}
}

// Print 为结构定义方法, 在方法前面定义一个接收者，那么这个TreeNode结构就有了print放
func (node Node) Print() {
	fmt.Println(node.Value)
}

// SetValue 定义set方法
func (node *Node) SetValue(value int) {
	if node == nil {
		fmt.Println("Setting Value to nil node.")
		return
	}
	node.Value = value
}
